using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Web.UI;
using System.Web.UI.Design;

namespace CodeStory.WebControls
{
	public class TreeNodeItem : IStateManager, ICloneable
	{
		private bool isTrackingViewState;
		private TreeGrid treeGrid;
		private TreeNodeItem _parent;
		private TreeNodeItemCollection nodeItems;
		private StateBag viewState;
		private bool _isRoot;
		private int _depth;
		private string _internalValuePath;
		private string _valuePath;
		private object _dataItem;

		public TreeNodeItem() {
			this._depth = -2;
		}

		public TreeNodeItem(TreeGrid treeGrid, bool isRoot) : this() {
			this.treeGrid = treeGrid;
			this._isRoot = isRoot;
		}

		public void LoadViewState(object state) {
			object[] objArray = (object[])state;
			if (objArray != null) {
				if (objArray[0] != null) {
					((IStateManager)this.ViewState).LoadViewState(objArray[0]);
					this.NotifyOwnerChecked();
				}
				if (objArray[1] != null) {
					((IStateManager)this.NodeItems).LoadViewState(objArray[1]);
				}
			}
		}

		private void NotifyOwnerChecked() {
		}

		public object SaveViewState() {
			object[] objArray = new object[2];
			if (this.viewState != null) {
				objArray[0] = ((IStateManager)this.viewState).SaveViewState();
			}
			if (this.nodeItems != null) {
				objArray[1] = ((IStateManager)this.nodeItems).SaveViewState();
			}
			if (objArray[0] == null && objArray[1] == null) {
				return null;
			}
			return objArray;
		}

		public void TrackViewState() {
			this.isTrackingViewState = true;
			if (this.viewState != null) {
				((IStateManager)this.viewState).TrackViewState();
			}
			if (this.nodeItems != null) {
				((IStateManager)this.nodeItems).TrackViewState();
			}
		}

		public bool IsTrackingViewState {
			get { return isTrackingViewState; }
		}
		public TreeGrid TreeGrid {
			get { return treeGrid; }
		}
		public TreeNodeItem Parent {
			get {
				if ((this._parent != null) && !this._parent._isRoot) {
					return this._parent;
				}
				return null;
			}
		}

		internal bool HasNodeItems {
			get {
				bool result = false;
				if (nodeItems != null) {
					if (NodeItems.Count > 0) result = true;
				}
				return result;
			}
		}

		public TreeNodeItemCollection NodeItems {
			get {
				if (nodeItems == null) {
					nodeItems = new TreeNodeItemCollection(this);
					if (this.isTrackingViewState) {
						((IStateManager)nodeItems).TrackViewState();
					}
				}
				return nodeItems;
			}
		}
		private StateBag ViewState {
			get {
				if (this.viewState == null) {
					this.viewState = new StateBag();
					if (this.isTrackingViewState) {
						((IStateManager)this.viewState).TrackViewState();
					}
				}
				return this.viewState;
			}
		}

		internal string InternalValuePath {
			get {
				if (this._internalValuePath == null) {
					if (this._parent == null) {
						return string.Empty;
					}
					List<string> list = new List<string>();
					list.Add(TreeGrid.Escape(this.Value));
					for (TreeNodeItem node = this._parent; (node != null) && !node._isRoot; node = node._parent) {
						if (node._internalValuePath != null) {
							list.Add(node._internalValuePath);
							break;
						}
						list.Add(TreeGrid.Escape(node.Value));
					}
					list.Reverse();
					this._internalValuePath = string.Join('\\'.ToString(), list.ToArray());
				}
				return this._internalValuePath;
			}
		}

		[DefaultValue("")]
		public string Text {
			get {
				string text = (string)this.ViewState["Text"];
				if (text == null) {
					text = (string)this.ViewState["Value"];
					if (text == null) {
						return string.Empty;
					}
				}
				return text;
			}
			set { this.ViewState["Text"] = value; }
		}

		[DefaultValue("")]
		public string Value {
			get {
				string text = (string)this.ViewState["Value"];
				if (text == null) {
					text = (string)this.ViewState["Text"];
					if (text == null) {
						return string.Empty;
					}
				}
				return text;
			}
			set {
				this.ViewState["Value"] = value;
				this.ResetValuePathRecursive();
			}
		}
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[Browsable(false)]
		[DefaultValue(false)]
		public bool DataBound {
			get {
				object obj = this.ViewState["DataBound"];
				return obj == null ? false : (bool)obj;
			}
		}
		[Browsable(false)]
		[DefaultValue((string)null)]
		public object DataItem {
			get { return this._dataItem; }
		}
		[Browsable(false)]
		[DefaultValue("")]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public string DataPath {
			get {
				object obj = this.ViewState["DataPath"];
				return obj == null ? string.Empty : (string)obj;
			}
		}
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int Depth {
			get {
				if (this._depth == -2) {
					if (this._isRoot) {
						return -1;
					}
					if (this.Parent == null) {
						if (this.treeGrid == null) {
							return 0;
						}
						this._depth = this.InternalValuePath.Split(new char[] {'\\'}).Length - 1;
					} else {
						this._depth = this.Parent.Depth + 1;
					}
				}
				return this._depth;
			}
		}

		[Editor(typeof(UrlEditor), typeof(UITypeEditor))]
		[DefaultValue("")]
		[UrlProperty]
		public string NavigateUrl {
			get {
				object obj = this.ViewState["NavigateUrl"];
				return obj == null ? string.Empty : (string)obj;
			}
			set { this.ViewState["NavigateUrl"] = value; }
		}

		[DefaultValue("")]
		public string Target {
			get {
				object obj = this.ViewState["Target"];
				return obj == null ? string.Empty : (string)obj;
			}
			set { this.ViewState["Target"] = value; }
		}
		[DefaultValue(false)]
		public bool PopulateOnDemand {
			get { 
				object obj = ViewState["PopulateOnDemand"];
				return obj == null ? false : (bool)obj;
			}
			set { ViewState["PopulateOnDemand"] = value; }
		}

		public TreeGridNodeState NodeState {
			get {
				object obj = ViewState["NodeState"];
				return obj == null ? TreeGridNodeState.Unknown : (TreeGridNodeState)obj;
			}
		}

		internal void ResetValuePathRecursive() {
			if (this._valuePath != null) {
				this._valuePath = null;
				foreach (TreeNodeItem node in this.NodeItems) {
					node.ResetValuePathRecursive();
				}
			}
		}

		public object Clone() {
			throw new NotImplementedException();
		}

		internal void SetDirty() {
			this.ViewState.SetDirty(true);
			if (this.nodeItems != null) {
				this.NodeItems.SetDirty();
			}
		}

		internal void SetTreeGrid(TreeGrid grid) {
			this.treeGrid = grid;
			if (this.nodeItems == null) return;
			foreach (TreeNodeItem child in NodeItems) {
				child.SetTreeGrid(grid);
			}
		}

		internal void SetParent(TreeNodeItem parent) {
			this._parent = parent;
			this.SetPath(null);
		}
		internal void SetDataItem(object dataItem) {
			this._dataItem = dataItem;
		}
		internal void SetDataPath(string dataPath) {
			this.ViewState["DataPath"] = dataPath;
		}

		private void SetPath(string newPath) {
			this._internalValuePath = newPath;
			this._depth = -2;
		}

		internal void SetDataBind(bool dataBind) {
			this.ViewState["DataBind"] = dataBind;
		}
		internal int GetChildItemCount() {
			return GetChildItemCount(this);
		}

		private int GetChildItemCount(TreeNodeItem item) {
			if (item.HasNodeItems) {
				int t = item.NodeItems.Count;
				foreach (TreeNodeItem n in item.NodeItems) {
					t += n.GetChildItemCount();
				}
				return t;
			} else {
				return 0;
			}
		}
	}
}